import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { RestService } from '../../services/rest.service';
import { TranslateService } from '@ngx-translate/core';
import { DialogTypes, ObjectTypes } from '../../models/wdl-types';

import * as _ from 'lodash';

@Component({
  selector: 'app-bobject',
  templateUrl: './bobject.component.html',
  styleUrls: ['./bobject.component.css']
})
export class BobjectComponent implements OnInit {
  @Input() item: any;
  @Input() type: ObjectTypes;

  @Output() refresh = new EventEmitter<any>();
  @Output() goto = new EventEmitter<any>();
  @Output() change = new EventEmitter<any>();

  user: any;

  url: string;
  total: number;

  constructor(private rest: RestService, private translate: TranslateService) {
    this.user = this.rest.getUser();
  }

  isUserQualified() {
    return this.user.role === 'header';
  }

  getType(): string {
    switch (this.type) {
    case ObjectTypes.BUILDING:
      return 'building';
    case ObjectTypes.LEVEL:
      return 'level';
    case ObjectTypes.ROOM:
      return 'room';
    case ObjectTypes.BED:
      return 'bed';
    }
  }

  getClass() {
    return this.getType();
  }

  getNameString() {
    return this.getType() + 'Name';
  }

  getTitle() {
    return this.item[this.getNameString()];
  }

  isBed() {
    return this.type === ObjectTypes.BED;
  }

  view() {
    this.goto.emit({
      item: this.item,
      type: this.type
    });
  }

  modify() {
    this.change.emit({
      item: this.item,
      type: this.type
    });
  }

  getTypeErrorMsgId(action) {
    return action + _.capitalize(this.getType()) + 'Message';
  }

  getTotalBed() {
    this.total = 0;
    switch (this.type) {
    case ObjectTypes.BUILDING:
      this.countBedInBuilding(this.item.id);
      break;
    case ObjectTypes.LEVEL:
      this.countBedInLevel(this.item.id);
      break;
    case ObjectTypes.ROOM:
      this.countBedInRoom(this.item.id);
      break;
    }
  }

  countBedInRoom(roomId) {
    this.rest.get('data/room/' + roomId + '/beds').subscribe(data => {
      this.total += data['_embedded']['beds'].length;
    });
  }

  countBedInLevel(levelId) {
    this.rest.get('data/level/' + levelId + '/rooms').subscribe(data => {
      data['_embedded']['rooms'].forEach(room => {
        this.countBedInRoom(room.id);
      });
    });
  }

  countBedInBuilding(buildingId) {
    this.rest.get('data/building/' + buildingId + '/levels').subscribe(data => {
      data['_embedded']['levels'].forEach(level => {
        this.countBedInLevel(level.id);
      });
    });
  }

  checkChild(succ, fail) {
    if (this.type === ObjectTypes.BED) {
      if (this.item.personId > 0) {
        if (fail) {
          fail();
        }
      } else {
        if (succ) {
          succ();
        }
      }
      return;
    }

    const childUrl = this.url + this.item.id + '/';
    let childName = '';
    switch (this.type) {
    case ObjectTypes.BUILDING:
      childName = 'levels';
      break;
    case ObjectTypes.LEVEL:
      childName = 'rooms';
      break;
    case ObjectTypes.ROOM:
      childName = 'beds';
      break;
    }

    this.rest.get(childUrl + childName).subscribe(data => {
      const children = data['_embedded'][childName];
      if (children && children.length > 0) {
        if (fail) {
          fail();
        }
      } else {
        if (succ) {
          succ();
        }
      }
    }, () => {
      if (fail) {
        fail();
      }
    });
  }

  remove() {
    this.checkChild(() => {
      this.doRemove();
    }, () => {
      const nonEmptyTitle = this.translate.get('deleteError')['value'];
      const nonEmptyMessage = this.getTypeErrorMsgId('nonEmpty');
      this.rest.openGenDialog(
        DialogTypes.ERROR,
        nonEmptyTitle,
        this.translate.get(nonEmptyMessage, this.type === ObjectTypes.BED ? {personName: this.item.personName} : {})['value'],
        null);
      return;
    });
  }

  doRemove() {
    const nameString = this.getNameString();
    const title = this.translate.get('deleteConfirmation')['value'];
    const message = this.translate.get(this.getTypeErrorMsgId('delete'), {nameString: this.item[nameString]})['value'];

    this.rest.openGenDialog(DialogTypes.CONFIRMATION, title, message, () => {
      this.rest.delete(this.url + this.item.id).subscribe(() => {
        this.refresh.emit();
      }, resp => {
        this.rest.showHttpError(this.translate.get('error')['value'], resp);
        this.refresh.emit();
      });
    });
  }

  ngOnInit() {
    this.url = 'data/' + this.getType() + '/';
    this.getTotalBed();
  }
}
